package com.fh.iot;

import com.fazecast.jSerialComm.*;
import javax.swing.*;
import java.awt.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.atomic.AtomicReference;

public class NikonThicknessGaugeApp extends JFrame {

    private SerialPort serialPort;
    private JComboBox<String> portComboBox;
    private JButton connectButton;
    private JButton disconnectButton;
    private JButton measureButton;
    private JTextArea logArea;
    private JLabel statusLabel;
    private JLabel measurementLabel;
    private boolean connected = false;
    AtomicReference<StringBuffer> sb= new AtomicReference<>(new StringBuffer());

    public NikonThicknessGaugeApp() {
        super("Nikon测厚仪控制程序");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(800, 500);
        setLayout(new BorderLayout());
        setLocationRelativeTo(null);

        // 创建顶部面板
        JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        portComboBox = new JComboBox<>();
        refreshPortList();
        topPanel.add(new JLabel("选择串口:"));
        topPanel.add(portComboBox);

        connectButton = new JButton("连接");
        connectButton.addActionListener(e -> connectToDevice());
        topPanel.add(connectButton);

        disconnectButton = new JButton("断开连接");
        disconnectButton.setEnabled(false);
        disconnectButton.addActionListener(e -> disconnect());
        topPanel.add(disconnectButton);

        measureButton = new JButton("测量厚度");
        measureButton.setEnabled(false);
        measureButton.addActionListener(e -> measureThickness());
        topPanel.add(measureButton);

        JButton refreshButton = new JButton("刷新串口");
        refreshButton.addActionListener(e -> refreshPortList());
        topPanel.add(refreshButton);

        add(topPanel, BorderLayout.NORTH);

        // 创建中间面板
        JPanel centerPanel = new JPanel(new BorderLayout());
        logArea = new JTextArea(10, 40);
        logArea.setEditable(false);
        logArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
        JScrollPane scrollPane = new JScrollPane(logArea);
        centerPanel.add(scrollPane, BorderLayout.CENTER);

        // 测量结果显示
        JPanel measurementPanel = new JPanel();
        measurementPanel.setBorder(BorderFactory.createTitledBorder("测量结果"));
        measurementPanel.setLayout(new BorderLayout());
        measurementLabel = new JLabel("等待测量...", JLabel.CENTER);
        measurementLabel.setFont(new Font("Arial", Font.BOLD, 24));
        measurementPanel.add(measurementLabel, BorderLayout.CENTER);

        centerPanel.add(measurementPanel, BorderLayout.SOUTH);
        add(centerPanel, BorderLayout.CENTER);

        // 创建底部状态栏
        statusLabel = new JLabel("就绪");
        statusLabel.setBorder(BorderFactory.createEtchedBorder());
        add(statusLabel, BorderLayout.SOUTH);

        setVisible(true);
    }

    private void refreshPortList() {
        portComboBox.removeAllItems();
        SerialPort[] ports = SerialPort.getCommPorts();
        for (SerialPort port : ports) {
            portComboBox.addItem(port.getSystemPortName() + " - " + port.getPortDescription());
        }
        if (ports.length == 0) {
            portComboBox.addItem("未检测到串口");
        }
    }

    private void connectToDevice() {
        if (connected) {
            logMessage("已连接到设备");
            return;
        }

        String selectedPort = (String) portComboBox.getSelectedItem();
        if (selectedPort == null || selectedPort.startsWith("未检测")) {
            logMessage("请选择有效的串口");
            return;
        }

        // 提取端口名称
        String portName = selectedPort.split(" - ")[0];



        try {
            serialPort = SerialPort.getCommPort(portName);
            serialPort.setBaudRate(4800);
            serialPort.setNumDataBits(8);
            serialPort.setNumStopBits(1);
            serialPort.setParity(SerialPort.NO_PARITY);
            serialPort.setFlowControl(SerialPort.FLOW_CONTROL_DISABLED);

            if (serialPort.openPort()) {
                logMessage("成功连接到端口: " + portName);
                statusLabel.setText("已连接: " + portName);
                connected = true;
                connectButton.setEnabled(false);
                disconnectButton.setEnabled(true);
                measureButton.setEnabled(true);


                // 添加数据监听器
                serialPort.addDataListener(new SerialPortDataListener() {
                    @Override
                    public int getListeningEvents() {
                        return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
                    }

                    @Override
                    public void serialEvent(SerialPortEvent event) {
                        if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE)
                            return;

                        byte[] buffer = new byte[serialPort.bytesAvailable()];
                        int numRead = serialPort.readBytes(buffer, buffer.length);
                        String data = new String(buffer, 0, numRead);
                        System.out.println("收到数据"+data);
                        // 处理接收到的数据
                        SwingUtilities.invokeLater(() -> {
                            logMessage("接收: " + data.trim());
                           processDeviceResponse(data);

                        });
                    }
                });
            } else {
                logMessage("无法打开端口: " + portName);
                statusLabel.setText("连接失败: " + portName);
            }
        } catch (Exception ex) {
            logMessage("连接错误: " + ex.getMessage());
            ex.printStackTrace();
        }
    }

    private void disconnect() {
        if (serialPort != null && serialPort.isOpen()) {
            serialPort.closePort();
            logMessage("已断开连接");
            statusLabel.setText("已断开连接");
        }
        connected = false;
        connectButton.setEnabled(true);
        disconnectButton.setEnabled(false);
        measureButton.setEnabled(false);
    }

    private void measureThickness() {
        if (!connected || serialPort == null) {
            logMessage("未连接到设备");
            return;
        }
        //QX\r\n
        // 发送测量命令（实际命令请参考设备手册）
        String command ="QX\r\n";// "MEASURE?\r\n";
        try {
            serialPort.writeBytes(command.getBytes(), command.getBytes().length);
            logMessage("发送: " + command.trim());
            //测试数据
            //testData();
        } catch (Exception ex) {
            logMessage("发送命令错误: " + ex.getMessage());
        }
    }
    //测量
    //0003.4567
//30  30 30 33 2E 34  35 36 37
    //ERROR
    //45 52 52 4F 52
    private void processDeviceResponse(String response) {
        // 在实际应用中，这里应该解析设备返回的数据
        // 这里我们模拟解析厚度值

        // 移除空白字符和非数字字符
        String cleanResponse = response.replaceAll("[^\\d.]", "");
        sb.get().append(cleanResponse);
//        System.out.println(sb.toString());
        if(sb.get().length()>8){
            if (!response.isEmpty()) {
                try {
                    double thickness = Double.parseDouble(sb.toString());
                    measurementLabel.setText(String.format("厚度: %.3f mm", thickness));
                    logMessage("成功测量厚度: " + thickness + " mm");
                } catch (NumberFormatException e) {
                    logMessage("无法解析测量数据: " + response);
                }
            } else {
                logMessage("收到空响应或无效数据: " + response);
            }
            sb.set(new StringBuffer());//重新初始化
        }else {
            if(sb.toString().indexOf("ERROR")>-1){
                logMessage("错误: " + sb.toString());
                sb.set(new StringBuffer());//重新初始化
            }
        //            System.out.println("还不够");
        }
    }

    private void logMessage(String message) {
        String timestamp = new SimpleDateFormat("HH:mm:ss").format(new Date());
        logArea.append("[" + timestamp + "] " + message + "\n");
        logArea.setCaretPosition(logArea.getDocument().getLength());
    }

    //模拟数据
    private  void testData(){
        String data="0003.67880003.6789ERROR";
        for (int i = 0; i < data.length(); i++) {
            String temp=data.substring(i,i+1);
            System.out.println(temp);
            processDeviceResponse(temp);
        }

    }

    public static void main(String[] args) {
        // 设置UI风格
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }

        new NikonThicknessGaugeApp();
    }
}